package com.salt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.salt.entity.UserInfo;
import com.salt.mapper.UserInfoMapper;
import com.salt.service.UserInfoService;
import com.salt.utils.UserContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 用户信息服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserInfo saveOrUpdateUserInfo(UserInfo userInfo) {
        // 参数校验
        if (userInfo == null) {
            throw new IllegalArgumentException("用户信息不能为空");
        }
        if (!StringUtils.hasText(userInfo.getName())) {
            throw new IllegalArgumentException("姓名不能为空");
        }
        if (!StringUtils.hasText(userInfo.getIdCard())) {
            throw new IllegalArgumentException("身份证信息不能为空");
        }
        if (!StringUtils.hasText(userInfo.getAlipayAccount())) {
            throw new IllegalArgumentException("支付宝账号不能为空");
        }
        if (userInfo.getBalance() == null) {
            throw new IllegalArgumentException("提现余额不能为空");
        }
        if (userInfo.getBalance().compareTo(BigDecimal.ZERO) < 0) {
            throw new IllegalArgumentException("提现余额不能小于0");
        }
        // 手机号不为空时，验证手机号格式
        if (StringUtils.hasText(userInfo.getMobile()) && !isValidMobile(userInfo.getMobile())) {
            throw new IllegalArgumentException("手机号格式不正确");
        }
        userInfo.setInviteCode(UserContext.getUser().getInviteCode());
        userInfo.setCreateTime(new Date());
        userInfo.setUpdateTime(new Date());
        save(userInfo);
        return userInfo;
    }

    @Override
    public UserInfo getByMobile(String mobile) {
        if (!StringUtils.hasText(mobile)) {
            return null;
        }
        
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getMobile, mobile);
        return getOne(wrapper);
    }

    @Override
    public List<UserInfo> getByInviteCode(String inviteCode) {
        if (!StringUtils.hasText(inviteCode)) {
            return null;
        }
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getInviteCode, inviteCode);
        return list(wrapper);
    }

    @Override
    public IPage<UserInfo> pageQueryByInviteCode(Page<UserInfo> page, String inviteCode, Integer status) {
        if (!StringUtils.hasText(inviteCode)) {
            return page;
        }
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getInviteCode, inviteCode)
               .eq(status != null, UserInfo::getState, status)
               .orderByDesc(UserInfo::getCreateTime);
        return page(page, wrapper);
    }

    @Override
    public BigDecimal getTotalBalance(String inviteCode) {
        if (!StringUtils.hasText(inviteCode)) {
            return BigDecimal.ZERO;
        }
        
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getInviteCode, inviteCode)
                .ne(UserInfo::getState,3)
               .select(UserInfo::getBalance);  // 只查询balance字段
        
        List<UserInfo> userInfoList = list(wrapper);
        
        // 计算总余额
        return userInfoList.stream()
                .map(userInfo -> userInfo.getBalance() != null ? userInfo.getBalance() : BigDecimal.ZERO)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 验证手机号格式
     * @param mobile 手机号
     * @return 是否有效
     */
    private boolean isValidMobile(String mobile) {
        return mobile != null && mobile.matches("^1[3-9]\\d{9}$");
    }
} 